<template>
  <div :class="cls">
    <div class="pro-timeline-item-dot-wrapper">
      <div :class="dotLineCls" :style="computedDotLineStyle" />
      <div class="pro-timeline-item-dot-content">
        <div v-if="$slots.icon" class="pro-timeline-item-dot-custom">
          <!-- 优先级高于 dotColor 和 dotType -->
          <slot name="icon" />
        </div>
        <div v-else :class="dotTypeCls" :style="computedDotStyle" />
      </div>
    </div>
    <div class="pro-timeline-item-content-wrapper">
      <div v-if="$slots.default" class="pro-timeline-item-content">
        <slot />
      </div>
      <div v-if="labelPosition !== 'relative'" class="pro-timeline-item-label">
        {{ label }}
      </div>
    </div>
    <div v-if="labelPosition === 'relative'" class="pro-timeline-item-label">
      {{ label }}
    </div>
  </div>
</template>

<script setup lang="ts" name="TimelineItem">
  import { ModeType, TimelineContext, timelineInjectionKey } from '../../type'
  import { Direction } from '../../constant'
  import { timelineItemProps } from '../../props'
  import { iconColor } from '~/types/timeLine'

  const props = defineProps(timelineItemProps)

  const getDefaultPosition = (
    index: number,
    mode: ModeType,
    direction: Direction,
    position?: string
  ) => {
    let map = ['left', 'right']
    if (direction === 'horizontal') {
      map = ['top', 'bottom']
    }
    const res = mode === 'alternate' ? position || map[index % 2] : mode
    return map.indexOf(res) > -1 ? res : map[0]
  }

  const context = inject<Partial<TimelineContext>>(timelineInjectionKey, {})
  const index = computed(() => props.index)

  const contextDirection = computed(() => {
    return context?.direction ?? 'vertical'
  })

  const labelPosition = computed(() => {
    return context?.labelPosition ?? 'same'
  })

  const cls = computed(() => {
    const { labelPosition, mode = 'left' } = context
    const direction = contextDirection.value
    const computedPosition = getDefaultPosition(
      index.value,
      mode,
      direction,
      props.position
    )
    return [
      'pro-timeline-item',
      {
        [`pro-timeline-item-${direction}-${computedPosition}`]: direction,
        [`pro-timeline-item-label-${labelPosition}`]: labelPosition
      }
    ]
  })

  const dotLineCls = computed(() => {
    return [
      `pro-timeline-item-dot-line`,
      `pro-timeline-item-dot-line-is-${contextDirection.value}`
    ]
  })

  const computedDotLineStyle = computed(() => {
    const { direction } = context! || {}
    return {
      [direction === 'horizontal' ? 'borderTopStyle' : 'borderLeftStyle']:
        props.lineType,
      ...(props.lineColor ? { borderColor: props.lineColor } : {})
    }
  })

  const dotTypeCls = computed(() => {
    return [`pro-timeline-item-dot`, `pro-timeline-item-dot-${props.dotType}`]
  })

  const computedDotStyle = computed(() => {
    return {
      [props.dotType === 'solid' ? 'backgroundColor' : 'borderColor']:
        props.dotColor ? props.dotColor : iconColor[props.type]
    }
  })
</script>

<style scoped lang="less">
  @import '../../style/index.less';
</style>
